package com.design.elegant.service;

import com.design.elegant.charge.BizEnum;
import com.design.elegant.charge.ChargeContext;
import com.design.elegant.charge.ChargeModel;
import com.design.elegant.charge.ChargeRequest;
import com.design.elegant.filters.ExceptionHandler;
import com.design.elegant.pipeline.FilterChainPipeline;
import com.design.elegant.pipeline.factory.FilterFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.plugin.core.PluginRegistry;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class ChargeServiceImpl implements IChargeService {

    @Resource
    private PluginRegistry<IChargeModelHandler, ChargeModel> pluginRegistry;

    @Autowired
    private FilterFactory filterFactory;

    @Autowired
    private ExceptionHandler exceptionHandler;

    @Override
    public void handle(ChargeRequest chargeRequest) {

        boolean present = BizEnum.of(chargeRequest.getBizCode()).isPresent();
        if (!present) {
            return;
        }
        BizEnum bizEnum = BizEnum.of(chargeRequest.getBizCode()).get();
        ChargeContext chargeContext = new ChargeContext(bizEnum);
        chargeContext.setChargeRequest(chargeRequest);
        FilterChainPipeline pipeline = filterFactory.createPipelineFromLocalConfig(chargeContext.getBizEnum());
        pipeline.setErrorHandler(exceptionHandler);
        pipeline.getFilterChain().handleAsync(chargeContext);
    }

    @Override
    public void handleWithAnno(ChargeRequest chargeRequest) {

        boolean present = BizEnum.of(chargeRequest.getBizCode()).isPresent();
        if (!present) {
            return;
        }
        BizEnum bizEnum = BizEnum.of(chargeRequest.getBizCode()).get();
        ChargeContext chargeContext = new ChargeContext(bizEnum);
        chargeContext.setChargeRequest(chargeRequest);
        FilterChainPipeline pipeline = filterFactory.createFilterChainPipelineWithAnno(chargeContext.getBizEnum());
        pipeline.setErrorHandler(exceptionHandler);
        pipeline.getFilterChain().handle(chargeContext);
    }
}
